package com.kimu.user.service;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

import jakarta.servlet.http.HttpServletRequest;

@Service
public class JwtService {

        @Value("${jwt.secret}")
        private String secret;

        private final KeyPair keyPair;

        private final long JWT_DURATION = 60000;

        public JwtService() throws Exception {
                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
                keyPairGenerator.initialize(2048);
                this.keyPair = keyPairGenerator.generateKeyPair();
        }

        /*
         * 根据用户名生成一个jwt, 同时设置持续时间
         */
        public String generateToken(String username) throws JOSEException {
                JWSSigner signer = new RSASSASigner((RSAPrivateKey) keyPair.getPrivate());
                JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                                .subject(username)
                                .issuer("http://localhost:8080")
                                .issueTime(new Date())
                                .expirationTime(new Date(System.currentTimeMillis() + JWT_DURATION))
                                .build();

                SignedJWT signedJWT = new SignedJWT(
                                new JWSHeader(JWSAlgorithm.RS256),
                                claimsSet);

                signedJWT.sign(signer);

                return signedJWT.serialize();
        }

        public boolean isTokenValid(String token) {
                try {
                        SignedJWT signedJWT = SignedJWT.parse(token);
                        signedJWT.verify(new RSASSAVerifier((RSAPublicKey) keyPair.getPublic()));
                        return true;
                } catch (Exception e) {
                        return false;
                }
        }

        public String extractUsername(String token) throws ParseException {
                SignedJWT signedJWT = SignedJWT.parse(token);
                return signedJWT.getJWTClaimsSet().getSubject();
        }

        /*
         * 从http request中获取jwt, 并解析得到用户名
         */
        public String getUsername(HttpServletRequest request) {
                String authHeader = request.getHeader("Authorization");
                // 如果解析出问题, 那么返回null
                String username = null;
                if (authHeader != null && authHeader.startsWith("Bearer ")) {
                        String jwt = authHeader.substring(7);

                        if (isTokenValid(jwt)) {
                                try {
                                        username = extractUsername(jwt);
                                } catch (ParseException e) {
                                        e.printStackTrace();
                                }
                        }
                }
                return username;
        }
}
